package repository

import (
	"boy-go/modules/generator/model"
	"boy-go/modules/generator/vo"
	"boy-go/pkg/db"
	"boy-go/pkg/request"
	"gorm.io/gorm"
)

var (
	_selectGenTableColumnVo = "column_id, table_id, column_name, column_comment, column_type, struct_type, struct_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time"
)

type GenTableColumnRepository struct {
	DB *gorm.DB
}

func NewGenTableColumnRepository() *GenTableColumnRepository {
	return &GenTableColumnRepository{
		DB: db.GetMasterDB(),
	}
}

func (r *GenTableColumnRepository) GetById(columnId int64) (*model.GenTableColumn, error) {
	db := r.DB
	m := &model.GenTableColumn{}
	err := db.Model(&model.GenTableColumn{}).Where("column_id = ?", columnId).First(m).Error
	if err != nil {
		return nil, err
	}
	return m, nil
}

func (r *GenTableColumnRepository) List(query *vo.QueryGenTableColumnReq, pageReq *request.PageRequest) ([]*model.GenTableColumn, int64, error) {
	tx := r.DB.Model(&model.GenTableColumn{})
	if query != nil {
		if query.TableId != nil {
			tx = tx.Where("table_id = ?", *query.TableId)
		}
		if query.ColumnName != nil {
			tx = tx.Where("column_name = ?", *query.ColumnName)
		}
		if query.ColumnComment != nil {
			tx = tx.Where("column_comment = ?", *query.ColumnComment)
		}
		if query.ColumnType != nil {
			tx = tx.Where("column_type = ?", *query.ColumnType)
		}
		if query.StructType != nil {
			tx = tx.Where("java_type = ?", *query.StructType)
		}
		if query.StructField != nil {
			tx = tx.Where("java_field = ?", *query.StructField)
		}
		if query.IsPk != nil {
			tx = tx.Where("is_pk = ?", *query.IsPk)
		}
		if query.IsIncrement != nil {
			tx = tx.Where("is_increment = ?", *query.IsIncrement)
		}
		if query.IsRequired != nil {
			tx = tx.Where("is_required = ?", *query.IsRequired)
		}
		if query.IsInsert != nil {
			tx = tx.Where("is_insert = ?", *query.IsInsert)
		}
		if query.IsEdit != nil {
			tx = tx.Where("is_edit = ?", *query.IsEdit)
		}
		if query.IsList != nil {
			tx = tx.Where("is_list = ?", *query.IsList)
		}
		if query.IsQuery != nil {
			tx = tx.Where("is_query = ?", *query.IsQuery)
		}
		if query.QueryType != nil {
			tx = tx.Where("query_type = ?", *query.QueryType)
		}
		if query.HtmlType != nil {
			tx = tx.Where("html_type = ?", *query.HtmlType)
		}
		if query.DictType != nil {
			tx = tx.Where("dict_type = ?", *query.DictType)
		}
		if query.Sort != nil {
			tx = tx.Where("sort = ?", *query.Sort)
		}
		if query.CreateBy != nil {
			tx = tx.Where("create_by = ?", *query.CreateBy)
		}
		if query.CreateTime != nil {
			tx = tx.Where("create_time = ?", *query.CreateTime)
		}
		if query.UpdateBy != nil {
			tx = tx.Where("update_by = ?", *query.UpdateBy)
		}
		if query.UpdateTime != nil {
			tx = tx.Where("update_time = ?", *query.UpdateTime)
		}
	}
	list := make([]*model.GenTableColumn, 0)
	if pageReq != nil {
		var total int64
		if err := tx.Count(&total).Error; err != nil {
			return nil, 0, err
		}
		if total > 0 {
			tx = tx.Select(_selectGenTableColumnVo)
			tx = db.BuildPageAndOrder(tx, &query.PageRequest, "")
			if err := tx.Find(&list).Error; err != nil {
				return nil, total, err
			}
		}
		return list, total, nil
	} else {
		tx = tx.Select(_selectGenTableColumnVo)
		if err := tx.Find(&list).Error; err != nil {
			return nil, 0, err
		}
	}
	return list, int64(len(list)), nil
}

func (r *GenTableColumnRepository) SelectGenTableColumnsByTableId(tableId int64) ([]*model.GenTableColumn, error) {
	list := make([]*model.GenTableColumn, 0)
	err := r.DB.Model(&model.GenTableColumn{}).Select(_selectGenTableColumnVo).Where("table_id = ?", tableId).Find(&list).Error
	return list, err
}

func (r *GenTableColumnRepository) SelectGenTableColumnsByTableIds(tableIds []*int64) ([]*model.GenTableColumn, error) {
	list := make([]*model.GenTableColumn, 0)
	err := r.DB.Model(&model.GenTableColumn{}).Select(_selectGenTableColumnVo).Where("table_id in ?", tableIds).Order("column_id,sort").Find(&list).Error
	return list, err
}

// Save 添加
func (r *GenTableColumnRepository) Save(m *model.GenTableColumn) error {
	return r.DB.Model(&model.GenTableColumn{}).Create(m).Error
}

// Update 更新
func (r *GenTableColumnRepository) Update(m *model.GenTableColumn) error {
	return r.DB.Model(&model.GenTableColumn{}).Where("column_id = ?", m.ColumnId).Updates(m).Error
}

// Delete 删除
func (r *GenTableColumnRepository) Delete(columnId int64) error {
	return r.DB.Model(&model.GenTableColumn{}).Where("column_id = ?", columnId).Delete(&model.GenTableColumn{}).Error
}

// DeleteBatch 批量删除
func (r *GenTableColumnRepository) BatchDelete(ids []string) error {
	db := r.DB
	db = db.Where("(column_id) IN ?", ids)
	return db.Delete(&model.GenTableColumn{}).Error
}

func (r *GenTableColumnRepository) SelectDbTableColumnsByName(tableName string) ([]*model.GenTableColumn, error) {
	sql := "select column_name as column_name, (case when (is_nullable = 'no' <> column_key != 'PRI') then '1' else '0' end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment as column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type as column_type" +
		" from information_schema.columns where table_schema = (select database()) and table_name = (?)" +
		" order by ordinal_position"
	list := make([]*model.GenTableColumn, 0)
	err := r.DB.Raw(sql, tableName).Find(&list).Error
	return list, err
}
